package com.chhuang.utils.bean;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

import com.chhuang.utils.string.StringUtil;

/**
 * bean辅助类
 * @author 黄晨
 * @date 2016-1-29
 *
 */
public class BeanHelper {
	
	private BeanHelper(){};

	/**
	 * 将对象的成员属性转换为map
	 * @param bean
	 * @return
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> bean2Map(Object bean) throws IllegalAccessException, 
		InvocationTargetException, NoSuchMethodException{
		return BeanUtils.describe(bean);
	}
	
	/**
	 * 将对象的成员属性转换为map
	 * @param bean
	 * @param excludeFields
	 * @return
	 * @throws IntrospectionException
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 */
	public static Map<String, Object> bean2Map(Object bean, List<String> excludeFields) throws IntrospectionException, 
		IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		Map<String, Object> map = new HashMap<String, Object>();
		BeanInfo bi = Introspector.getBeanInfo(bean.getClass());
		PropertyDescriptor[] pds = bi.getPropertyDescriptors();
		for (int i=0; i<pds.length; i++) {
			String propName = pds[i].getName();
			if (excludeFields.contains(propName))
				continue;
			String propValue = BeanUtils.getSimpleProperty(bean, propName);
			if (StringUtil.isNotEmpty(propValue))
				map.put(propName, propValue);
		}
		return map;
	}
	
	/**
	 * map转bean
	 * @param clazz
	 * @param map
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static <T, V> T map2Bean(Class<T> clazz, Map<String, V> map) throws InstantiationException, 
		IllegalAccessException, InvocationTargetException{
		T object = clazz.newInstance();
		BeanUtils.populate(object, map);
		return object;
	}
}
